﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TrainingDemo.Model;
using TrainingDemo.Util.NativeUtil;

namespace TrainingDemo
{
    public partial class frmMain : Form
    {

        #region Construction/Destruction/Initialize

        public frmMain()
        {
            InitializeComponent();
        }


        private void frmMain_Load(object sender, EventArgs e)
        {
            onLoad();
        }

        private void onLoad()
        {
            DesktopBinding();
            TechnologyBinding();
            DisplayInformation();

            cmbTechnology.Visible = false;
            lblTechnology.Visible = false;
            btnIntake.Visible = false;
        }

        private void DesktopBinding()
        {
            tvWindows.Nodes.Clear();
            tvControls.Nodes.Clear();
            tblPropertyView.Rows.Clear();
            List<IntPtr> lstTopMost = new List<IntPtr>();
            NativeUtils.getListDesktopWindows(IntPtr.Zero, ref lstTopMost, true);
            foreach (IntPtr pHandle in lstTopMost)
            {
                TreeNode pWindow = new WindowsNode(pHandle, NativeUtils.GetWindowTitle(pHandle, 255));
                tvWindows.Nodes.Add(pWindow);
                //tvWindows.Nodes.Add(NativeUtils.GetWindowTitle(pHandle, 255));
            }

            tvWindows.Refresh();
        }

        private void ControlBinding()
        {

        }


        private void TechnologyBinding()
        {

            // bind technology into cmbTechnology
            List<TechnologyBridge> lstTechnologies = new List<TechnologyBridge> {
                TechnologyHook.getInstance(),    
                TechnologyAccessibility.getInstance(), 
                TechnologyJavaReflection.getInstance(),
                TechnologyNetReflection.getInstance(),
                TechnologyInjectCode.getInstance()
                };


            cmbTechnology.DataSource = lstTechnologies;
            cmbTechnology.DisplayMember = "Name";
            cmbTechnology.SelectedIndex = -1;
        }

        #endregion


        #region Private Property

        List<ControlWrapper> m_lstControl;

        #endregion


        #region Public Methods




        #endregion


        #region Private Methods

        void DisplayInformation()
        {
            lblWindowsNumber.Text = tvWindows.GetNodeCount(true).ToString();
            lblControlNumber.Text = tvControls.GetNodeCount(true).ToString();
        }


        #endregion


        #region EventHandler

        private void tvWindows_AfterSelect(object sender, TreeViewEventArgs e)
        {
            WindowsNode pNode = (WindowsNode)e.Node;
            //MessageBox.Show("Window " + pNode.Handle.ToInt32().ToString() + " has title " + pNode.Title + " is selected");

            lblTechnology.Visible = true;
            cmbTechnology.Visible = true;
            btnIntake.Visible = true;
        }

        private void btnIntake_Click(object sender, EventArgs e)
        {
            string strInfor = tvWindows.SelectedNode.Text;
            if (strInfor.Equals(String.Empty))
            {
                MessageBox.Show("Please select at least 1 windows");
                return;
            }

            if (cmbTechnology.SelectedIndex == -1)
            {
                MessageBox.Show("Please select at least 1 technology");
                return;
            }

            if (strInfor.Length > 20)
            {
                strInfor = strInfor.Substring(0, 20) + "...";
            }
            lblListControl.Text = "List control of window " + strInfor;

            // intake control based on selected technology
            m_lstControl = new List<ControlWrapper>();
            WindowsNode selectedNode = tvWindows.SelectedNode as WindowsNode;
            int nRes = IntakeControl(cmbTechnology.SelectedItem, selectedNode.Handle, ref m_lstControl);

            if (nRes == Const.AUTO_OK)
            {
                // Display list of control
                ControlNode tempNode = null;
                foreach (ControlWrapper control in m_lstControl)
                {
                    tempNode = new ControlNode(IntPtr.Zero, control.ControlName);
                    tvControls.Nodes.Add(tempNode);
                }
            }
        }

        private void tvControls_AfterSelect(object sender, TreeViewEventArgs e)
        {
            ControlNode pNode = (ControlNode)e.Node;
            string controlName = pNode.Title;
            Dictionary<string, string> propsMap = new Dictionary<string, string>();
            
            int nRes = GetSupportedPropertiesAndValue(cmbTechnology.SelectedItem, controlName, ref propsMap);
            if (nRes == Const.AUTO_OK)
            {
                tblPropertyView.Rows.Clear();
                DataGridViewRow row = null;// new DataGridViewRow();

                foreach (KeyValuePair<string, string> item in propsMap)
                {
                    row = new DataGridViewRow();
                    row.Cells.Add(new DataGridViewTextBoxCell() { Value = item.Key });
                    row.Cells.Add(new DataGridViewTextBoxCell() { Value = item.Value });
                    tblPropertyView.Rows.Add(row);
                }
            }

            //grdProperty = propsMap.GetEnumerator();
        }

        private int GetSupportedPropertiesAndValue(object objTechnology, string controlName, ref Dictionary<string, string> propsMap)
        {
            int nResult = Const.AUTO_FALSE;
            if (objTechnology != null)
            {
                string szProperties = "";
                TechnologyBridge pTechnology = objTechnology as TechnologyBridge;

                nResult = pTechnology.getSupportedProperty(controlName, ref szProperties, Const.AUTO_MAX_LENGTH);
                if (nResult == Const.AUTO_OK)
                {
                    string propValue = "";
                    string[] lstPropName = szProperties.Split(new string[] { Const.AUTO_SPLIT }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string propName in lstPropName)
                    {
                        int nRes = pTechnology.getProperty(controlName, propName, ref propValue, Const.AUTO_MAX_LENGTH);
                        if (nRes == Const.AUTO_OK)
                        {
                            propsMap.Add(propName, propValue);
                        }
                    }
                }
                else if (nResult > Const.AUTO_FALSE)
                {
                    nResult = pTechnology.getSupportedProperty(controlName, ref szProperties, nResult);
                    if (nResult == Const.AUTO_OK)
                    {
                        string propValue = "";
                        string[] lstPropName = szProperties.Split(new string[] { Const.AUTO_SPLIT }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (string propName in lstPropName)
                        {
                            int nRes = pTechnology.getProperty(controlName, propName, ref propValue, Const.AUTO_MAX_LENGTH);
                            if (nRes == Const.AUTO_OK)
                            {
                                propsMap.Add(propName, propValue);
                            }
                        }
                    }
                }
            }
            return nResult;
        }

        private int IntakeControl(object objTechnology, IntPtr pHandle, ref List<ControlWrapper> lstControl)
        {
            int nResult = Const.AUTO_FALSE;
            if (objTechnology != null)
            {
                string szChildrenName = "";
                TechnologyBridge pTechnology = objTechnology as TechnologyBridge;
                nResult = pTechnology.getChildren(pHandle, ref szChildrenName, Const.AUTO_MAX_LENGTH);
                if (nResult == Const.AUTO_OK)
                {
                    string[] lstControlName = szChildrenName.Split(new string[] { Const.AUTO_SPLIT }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string item in lstControlName)
                    {
                        m_lstControl.Add(new ControlWrapper(IntPtr.Zero, item));
                    }
                }
                else if (nResult > Const.AUTO_FALSE)
                {
                    nResult = pTechnology.getChildren(pHandle, ref szChildrenName, nResult);
                    if (nResult == Const.AUTO_OK)
                    {
                        string[] lstControlName = szChildrenName.Split(new string[]{Const.AUTO_SPLIT}, StringSplitOptions.RemoveEmptyEntries);
                        foreach (string item in lstControlName)
                        {
                            m_lstControl.Add(new ControlWrapper(IntPtr.Zero, item));
                        }
                    }
                }
            }
            return nResult;
        }

        #endregion
    }
}
